package com.fuyao.cloud.personnel.problem.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.admin.api.dto.UserInfoParamsDTO;
import com.fuyao.cloud.admin.api.entity.SysDept;
import com.fuyao.cloud.admin.api.feign.RemoteDeptService;
import com.fuyao.cloud.admin.api.feign.RemoteUserInfoService;
import com.fuyao.cloud.admin.api.feign.RemoteUserService;
import com.fuyao.cloud.admin.api.utils.NumberUtils;
import com.fuyao.cloud.admin.api.vo.UserInfoDeptVO;
import com.fuyao.cloud.admin.api.vo.UserVO;
import com.fuyao.cloud.common.core.constant.SecurityConstants;
import com.fuyao.cloud.common.core.util.R;
import com.fuyao.cloud.common.data.datascope.DataScope;
import com.fuyao.cloud.common.excel.vo.ErrorMessage;
import com.fuyao.cloud.common.security.service.CloudUser;
import com.fuyao.cloud.common.security.util.SecurityUtils;
import com.fuyao.cloud.personnel.api.constant.ProblemInfoConstant;
import com.fuyao.cloud.personnel.api.constant.RectifyConstant;
import com.fuyao.cloud.personnel.api.dto.ProblemRectifyDTO;
import com.fuyao.cloud.personnel.api.entity.ProblemFeedback;
import com.fuyao.cloud.personnel.api.entity.ProblemInfor;
import com.fuyao.cloud.personnel.api.entity.ProblemRectify;
import com.fuyao.cloud.personnel.api.entity.ProblemRectifyDetailed;
import com.fuyao.cloud.personnel.api.vo.RectifyThoseResponsibleVO;
import com.fuyao.cloud.personnel.api.vo.RegularlyRemind;
import com.fuyao.cloud.personnel.api.vo.excel.ProblemRectifyExcelExportVO;
import com.fuyao.cloud.personnel.api.vo.excel.ProblemRectifyExcelVO;
import com.fuyao.cloud.personnel.problem.mapper.ProblemFeedbackMapper;
import com.fuyao.cloud.personnel.problem.mapper.ProblemInforMapper;
import com.fuyao.cloud.personnel.problem.mapper.ProblemRectifyDetailedMapper;
import com.fuyao.cloud.personnel.problem.mapper.ProblemRectifyMapper;
import com.fuyao.cloud.personnel.problem.service.ProblemRectifyDetailedService;
import com.fuyao.cloud.personnel.problem.service.ProblemRectifyService;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;

import java.util.*;

/**
 * 整改措施
 *
 * @author pigx code generator
 * @date 2022-04-26 10:14:04
 */
@Service
@AllArgsConstructor
public class ProblemRectifyServiceImpl extends ServiceImpl<ProblemRectifyMapper, ProblemRectify> implements ProblemRectifyService {

    private final RemoteDeptService remoteDeptService;

    private final RemoteUserService remoteUserService;

    private final ProblemRectifyDetailedMapper rectifyDetailedMapper;
    private final ProblemRectifyDetailedService  problemRectifyDetailedService;
    private final ProblemFeedbackMapper feedbackMapper;

    private final ProblemInforMapper problemInforMapper;

    private final RemoteDeptService deptService;

    private final RemoteUserInfoService userInfoService;

    @Override
    public IPage<RectifyThoseResponsibleVO>  pageRectifyThoseResponsibleVO(Page page, RectifyThoseResponsibleVO queryWrapper) {
        return this.baseMapper.selectPageRectifyThoseResponsibleVO(page,queryWrapper,new DataScope());
    }

    @Override
    public R importProblemRectify(List<ProblemRectifyExcelVO> excelVOList, BindingResult bindingResult) {
        // 通用校验获取失败的数据
        List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
        List<ProblemInfor> problemInforList = this.problemInforMapper.selectList(Wrappers.emptyWrapper());

        CloudUser user = SecurityUtils.getUser();
        UserInfoParamsDTO paramsDTO = new UserInfoParamsDTO();
        paramsDTO.setTenantId(user.getTenantId());
        List<UserInfoDeptVO> userDeptList = userInfoService.getUserDetailInfoList(paramsDTO, SecurityConstants.FROM_IN).getData();

        List<SysDept> deptList = deptService.deptAll().getData();

        for (int i = 0; i < excelVOList.size(); i++) {
            ProblemRectifyExcelVO rectifyExcelVO = excelVOList.get(i);
            Set<String> errorMsg = new HashSet<>();

            // List<ProblemInfor> problemInfors = this.problemInforMapper.selectList(Wrappers.<ProblemInfor>lambdaQuery().eq(ProblemInfor::getNumber,rectifyExcelVO.getProblemInforNum()));
            ProblemInfor problemInfor = problemInforList.stream().filter(pInfor -> pInfor.getNumber().equals(rectifyExcelVO.getProblemInforNum())).findFirst().orElse(null);
            if (problemInfor == null){
                errorMsg.add(String.format("问题单号在系统中不存在"));
            }

            if(checkImportProblemRectifyExists(rectifyExcelVO.getProblemInforNum(),rectifyExcelVO.getDescribeText())){
                errorMsg.add(String.format("%s","整改措施已存在"));
            }

            if (rectifyExcelVO.getTimelimitType().equals(RectifyConstant.CYCLE)){
                if (rectifyExcelVO.getStartdate() == null){
                    errorMsg.add(String.format("期限完成开始时间不能为空"));
                }
                if (rectifyExcelVO.getEnddate() == null){
                    errorMsg.add(String.format("期限完成规定完成时间不能为空"));
                }
            }

            // 数据合法情况
            if (CollUtil.isEmpty(errorMsg)) {
                insertExcelRectify(rectifyExcelVO,problemInfor,userDeptList,deptList);
            }
            else {
                // 数据不合法情况
                errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
            }
        }

        if (CollUtil.isNotEmpty(errorMessageList)) {
            return R.failed(errorMessageList);
        }

        return R.ok();
    }

    private boolean checkImportProblemRectifyExists(String problemInforNum,String describeText){
        if(StrUtil.isEmpty(problemInforNum) || StrUtil.isEmpty(describeText)){
            return false;
        }
        LambdaQueryWrapper<ProblemRectify> queryWrapper = Wrappers.<ProblemRectify>query().lambda()
                .eq(ProblemRectify::getProblemInforNum, problemInforNum)
                .eq(ProblemRectify::getDescribeText, describeText);
        Long count = this.baseMapper.selectCount(queryWrapper);
        return (null!=count && count>0);
    }

    private void insertExcelRectify(ProblemRectifyExcelVO rectifyExcelVO,ProblemInfor problemInfor,List<UserInfoDeptVO> userDeptList,List<SysDept> deptList) {
        ProblemRectify rectify =new ProblemRectify();
        BeanUtils.copyProperties(rectifyExcelVO,rectify);
        rectify.setProblemInforId(problemInfor.getId());
        rectify.setProblemInforNum(problemInfor.getNumber());
        rectify.setNumber(getOnlyNum());

        switch (StrUtil.emptyToDefault(rectifyExcelVO.getTimelimitType(),"长期")){
            case RectifyConstant.CYCLE:
                rectify.setTimelimitType(RectifyConstant.CYCLE_VAL);
                break;
            case RectifyConstant.LONG_TIME:
                rectify.setTimelimitType(RectifyConstant.LONG_TIME_VAL);
                rectify.setStartdate(null);
                rectify.setEnddate(null);
                break;
            case RectifyConstant.VERTICAL_LINE_CHANGE:
                rectify.setTimelimitType(RectifyConstant.VERTICAL_LINE_CHANGE_VAL);
                rectify.setStartdate(null);
                rectify.setEnddate(null);
                break;
            default:
                rectify.setTimelimitType(RectifyConstant.LONG_TIME_VAL);
                rectify.setStartdate(null);
                rectify.setEnddate(null);
                break;
        }
        switch (StrUtil.emptyToDefault(rectifyExcelVO.getCompletion(),"未完成")){
            case RectifyConstant.HAS_RECTIFICATION:
                rectify.setCompletion(RectifyConstant.HAS_RECTIFICATION_VAL);
                break;
            case RectifyConstant.INSIST_LONG_TIME:
                rectify.setCompletion(RectifyConstant.INSIST_LONG_TIME_VAL);
                break;
            case RectifyConstant.NEED_LOOK_BACK:
                rectify.setCompletion(RectifyConstant.NEED_LOOK_BACK_VAL);
                break;
            case RectifyConstant.ONGOING:
                rectify.setCompletion(RectifyConstant.ONGOING_VAL);
                break;
            case RectifyConstant.UNFINISHED:
                rectify.setCompletion(RectifyConstant.UNFINISHED_VAL);
                break;
            default:
                rectify.setCompletion(RectifyConstant.UNFINISHED_VAL);
                break;
        }
        Optional<SysDept> deptOptional = deptList.stream().filter(sysDept -> sysDept.getFullName().equals(rectifyExcelVO.getFunctionalName())).findFirst();
        // R<SysDept> rfundept=  this.deptService.dept();
        if (deptOptional.isPresent()){
            SysDept dept = deptOptional.get();
            rectify.setFunctionalOuid(dept.getDeptId());
            rectify.setFunctionalName(dept.getName());
            rectify.setFunctionalFullname(dept.getFullName());
        }
        boolean save = super.save(rectify);
        if(save){
            updateProbemInforStatus(rectify.getProblemInforNum());
        }
        if (StringUtils.hasLength(rectifyExcelVO.getThoseResponsibles())){
            String[] tr = rectifyExcelVO.getThoseResponsibles().split("(;|；|,)");
            if (tr.length > 0){
                for (int i = 0; i < tr.length; i++) {
                    ProblemRectifyDetailed rectifyDetailed =new ProblemRectifyDetailed();
                    rectifyDetailed.setRectifyId(rectify.getId());
                    rectifyDetailed.setRectifyNum(rectify.getNumber());
                    // R<SysUserinfo> rUserInfo= this.userInfoService.getByPersonnelNum(tr[i]);
                    String userNameTemp = tr[i].replaceAll("\r|\n*","");

                    Optional<UserInfoDeptVO> userInfoDeptOptional = userDeptList.stream().filter(userInfoDeptVO -> f(userInfoDeptVO, userNameTemp)).findFirst();
                    if(userInfoDeptOptional.isPresent()){
                        UserInfoDeptVO userInfoDeptVO = userInfoDeptOptional.get();
                        rectifyDetailed.setDutyUserid(userInfoDeptVO.getUserId());
                        rectifyDetailed.setDutyUsername(userInfoDeptVO.getName());
                        rectifyDetailed.setDutyName(userInfoDeptVO.getDeptName());
                        rectifyDetailed.setDutyOuid(userInfoDeptVO.getDeptId());
                        rectifyDetailed.setDutyFullname(userInfoDeptVO.getDeptFullname());
                    }else{
                        rectifyDetailed.setDutyUsername(userNameTemp);
                    }
                    this.rectifyDetailedMapper.insert(rectifyDetailed);
                }
            }
        }
    }

    @Override
    public List<ProblemRectifyExcelExportVO> getProblemRectifyExcelListVO(Page page, RectifyThoseResponsibleVO problemRectify) {
        Page resultPage = this.baseMapper.selectPageRectifyThoseResponsibleVO(page, problemRectify, new DataScope());
        List<RectifyThoseResponsibleVO> records = resultPage.getRecords();
        List<ProblemRectifyExcelExportVO> exportResultList = Lists.newArrayList();
        if(CollUtil.isNotEmpty(records)){
            records.forEach(rectify -> {
                ProblemRectifyExcelExportVO excelExportVO = new ProblemRectifyExcelExportVO();
                BeanUtils.copyProperties(rectify,excelExportVO);
                excelExportVO.setInfor(rectify.getInfor());
                excelExportVO.setSource(rectify.getSource());
                excelExportVO.setCompletion(RectifyConstant.completionMap.get(rectify.getCompletion()));
                excelExportVO.setTimelimitType(RectifyConstant.timelimitTypeMap.get(rectify.getTimelimitType()));
                excelExportVO.setFunctionalName(rectify.getFunctionalFullname());
                exportResultList.add(excelExportVO);
            });
        }
        return exportResultList;
    }

    private boolean f(UserInfoDeptVO userInfoDeptVO, String userName){
        return userName.equals(userInfoDeptVO.getName());
    }

    @Override
    public boolean save(ProblemRectify entity) {
        entity.setNumber(getOnlyNum());
        setFuncationDept(entity);
        if (!RectifyConstant.CYCLE_VAL.equals(entity.getTimelimitType())){
            entity.setStartdate(null);
            entity.setEnddate(null);
        }
        AssertUtil.isTrue(!checkImportProblemRectifyExists(entity.getProblemInforNum(),entity.getDescribeText()),"整改描述已存在，请修改整改措施内容");
        boolean save = super.save(entity);
        setProblemRectifyDetailedList(entity,entity.getThoseResponsibleIds());
        updateProbemInforStatus(entity.getProblemInforNum());
        return save;
    }

    @Override
    public boolean updateById(ProblemRectify entity) {
        setFuncationDept(entity);
        if (!entity.getTimelimitType().equals(RectifyConstant.CYCLE_VAL)){
            entity.setStartdate(null);
            entity.setEnddate(null);
        }
        setProblemRectifyDetailedList(entity,entity.getThoseResponsibleIds());
        boolean update = super.updateById(entity);
        if(update){
            updateProbemInforStatus(entity.getProblemInforNum());
        }
        return update;
    }
    private void setProblemRectifyDetailedList(ProblemRectify rectify,List<Long> thoseResponsibleIds){
        if(CollUtil.isNotEmpty(thoseResponsibleIds)){
            problemRectifyDetailedService.save(rectify,thoseResponsibleIds);
        }
    }

    public String getOnlyNum() {
        // 默认
        String onlyNum = "00001";
        ProblemRectify infor = this.baseMapper.selectOne(Wrappers.<ProblemRectify>lambdaQuery().orderByDesc(ProblemRectify::getId).last("LIMIT 1"));
        if (infor != null) {
            onlyNum = NumberUtils.getIncrementNum(infor.getNumber().substring(10));
        }
        return RectifyConstant.RECTIFY_NUM_PREFIX + DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN) + onlyNum;
    }

    private void setFuncationDept(ProblemRectify entity) {
        if (entity.getFunctionalOuid() != null && entity.getFunctionalOuid() > 0) {
            SysDept dept = this.remoteDeptService.getById(entity.getFunctionalOuid()).getData();
            if (dept != null) {
                entity.setFunctionalFullname(dept.getFullName());
                entity.setFunctionalName(dept.getName());
            }
        }
    }

    @Override
    public List<RegularlyRemind> getRegularlyReminds(Long id) {
        List<ProblemRectifyDetailed> problemRectifyDetaileds = this.rectifyDetailedMapper.selectList(Wrappers.<ProblemRectifyDetailed>lambdaQuery().eq(ProblemRectifyDetailed::getRectifyId, id));
        List<RegularlyRemind> regularlyReminds = new ArrayList<>();
        for (int i = 0; i < problemRectifyDetaileds.size(); i++) {
            UserVO userVO = remoteUserService.userAndDept(problemRectifyDetaileds.get(i).getDutyUserid()).getData();
            RegularlyRemind regularlyRemind = new RegularlyRemind();
            regularlyRemind.setUsername(userVO.getUsername());
            regularlyRemind.setRealName(problemRectifyDetaileds.get(i).getDutyUsername());
            regularlyRemind.setDeptName(userVO.getDeptName());
            regularlyRemind.setEmail(userVO.getEmail());
            regularlyRemind.setRealPhone(userVO.getRealPhone());
            regularlyRemind.setUserOuid(userVO.getDeptId());
            regularlyRemind.setUserOuname(userVO.getDeptName());
            regularlyRemind.setUserOufullname(userVO.getDeptFullName());
            regularlyRemind.setUserUserid(userVO.getUserId());
            regularlyRemind.setSourceId(id);
            regularlyRemind.setSourceType(ProblemRectifyDetailed.class.getName());
            regularlyRemind.setDeptId(userVO.getDeptId());
            regularlyRemind.setUserId(userVO.getUserId());
            regularlyReminds.add(regularlyRemind);
        }
        return regularlyReminds;
    }

    @Override
    public String getInforName(Long id) {
        ProblemRectify rectify = this.baseMapper.selectById(id);
        ProblemInfor infor = this.problemInforMapper.selectById(rectify.getProblemInforId());
        return infor.getInfor();
    }

    @Override
    public boolean saveRectifyAndResponsPerson(ProblemRectifyDTO rectifyDTO) {
        rectifyDTO.setNumber(getOnlyNum());
        setFuncationDept(rectifyDTO);
        ProblemRectify rectify = new ProblemRectify();
        BeanUtils.copyProperties(rectifyDTO,rectify);

        AssertUtil.isTrue(!checkImportProblemRectifyExists(rectify.getProblemInforNum(),rectify.getDescribeText()),"整改描述已存在，请修改整改措施内容");
        boolean save = super.save(rectify);
        if(save){
            updateProbemInforStatus(rectify.getProblemInforNum());
        }
        /*List<ProblemRectifyDetailed> rectifyDetaileds = rectifyDTO.getRectifyDetaileds();
        if (rectifyDetaileds!=null){
            for (int i = 0; i < rectifyDetaileds.size(); i++) {
                ProblemRectifyDetailed rectifyDetailed = rectifyDetaileds.get(i);
                rectifyDetailed.setRectifyId(rectify.getId());
                rectifyDetailed.setRectifyNum(rectify.getNumber());
                this.rectifyDetailedMapper.insert(rectifyDetailed);
        }*/
        List<Long> thoseResponsibleIds = rectifyDTO.getThoseResponsibleIds();
        setProblemRectifyDetailedList(rectify,thoseResponsibleIds);
        return save;
    }

    @Override
    public R batchRemoveRectifyByIds(List<Long> ids) {
        StringBuilder resultMessage = new StringBuilder();
        // 删除整改措施责任人
        int deleteDetailed = rectifyDetailedMapper.delete(Wrappers.<ProblemRectifyDetailed>lambdaQuery().in(ProblemRectifyDetailed::getRectifyId,ids));
        // 删除整改进展反馈
        int deleteFeedback = feedbackMapper.delete(Wrappers.<ProblemFeedback>lambdaQuery().in(ProblemFeedback::getRectifyId,ids));
        // 删除整改措施
        int deleteRectify = this.baseMapper.deleteBatchIds(ids);

        resultMessage.append("成功删除整改措施%s条，");
        resultMessage.append("删除关联整改进展反馈%s条，");
        resultMessage.append("删除关联整改措施责任人%s条。");
        return R.ok(String.format(resultMessage.toString(),deleteRectify,deleteFeedback, deleteDetailed));
    }

    private void updateProbemInforStatus(String problemInforNum){
        // HAS_RECTIFICATION_VAL 查询措施状态不等于 1已整改
        long count = this.count(Wrappers.<ProblemRectify>query().lambda().eq(ProblemRectify::getProblemInforNum, problemInforNum).notIn(ProblemRectify::getCompletion,RectifyConstant.HAS_RECTIFICATION_VAL));
        int updateStatus = (count == 0? ProblemInfoConstant.HAS_BEEN_COMPLETED_VAL:ProblemInfoConstant.PROCESSING_VAL);

        ProblemInfor problemInfor = problemInforMapper.selectOne(Wrappers.<ProblemInfor>query().lambda().eq(ProblemInfor::getNumber, problemInforNum));
        if(ObjectUtil.isNotEmpty(problemInfor)){
            problemInfor.setStatus(updateStatus);
            problemInforMapper.updateById(problemInfor);
        }
    }
}
